
package com.taxshare.seller.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.collection.CollUtil;
import com.taxshare.seller.entity.*;
import com.taxshare.seller.view.vo.*;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taxshare.mybatis.utils.DozerBeanUtil;
import com.taxshare.response.beans.Response;
import com.taxshare.seller.constant.CodeConstant;
import com.taxshare.seller.mapper.GoodsManageMapper;
import com.taxshare.seller.mapper.InvoiceDetailMapper;
import com.taxshare.seller.mapper.InvoicedMapper;
import com.taxshare.seller.mapper.SupplierInfoMapper;
import com.taxshare.seller.remote.ApiClientService;
import com.taxshare.seller.util.sst.IntJsonUtil;
import com.taxshare.seller.view.dto.GoodsManageDTO;
import com.taxshare.seller.view.dto.SellerInvoiceDTO;
import com.taxshare.tools.token.UserInfoUtil;
import com.taxshare.tools.util.UUIDUitl;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;

import javax.sql.DataSource;


/**
 * @author liupp
 * @ClassName: ManualOpenInvoiceService
 * @Description: (手工开票)
 * @date 2021年4月14日
 */

@Service
@Slf4j
public class ManualOpenInvoiceService extends ServiceImpl<InvoicedMapper, SellerInvoiceEntity> {

    @Autowired
    private OpenInvoiceService openInvoiceService;
    @Autowired
    ApiClientService apiClientService;
    @Autowired
    private GoodsManageMapper goodsManageMapper;
    @Autowired
    private SupplierInfoMapper supplierInfoMapper;
    @Autowired
    private InvoicedMapper invoicedMapper;
    @Autowired
    private InvoiceDetailMapper invoiceDetailMapper;
    @Autowired
    private static JdbcTemplate jdbcTemplate;
    @Autowired
    private PlatformTransactionManager txManager;
    @Autowired
    private DataSource dataSource;
    @Autowired
    AlsTenantInfoService alsTenantInfoService;

    @Autowired
    CommService commService;


    /**
     * 查询商品
     *
     * @param goodsManageDTO
     * @return
     */

    public Response getSubData(GoodsManageDTO goodsManageDTO) {
        QueryWrapper<GoodsManageEntity> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(goodsManageDTO.getGoodsName())) {
            queryWrapper.like("goods_name", goodsManageDTO.getGoodsName());
        }
        List<GoodsManageEntity> resDataList = goodsManageMapper.selectList(queryWrapper);
        return Response.success(resDataList);
    }


    /**
     * 智能抬头
     *
     * @param gfmc
     * @return
     */

    public Response getInvoiceHead(String gfmc, String sellerTaxNo) {
        QueryWrapper<AlsTenantInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_no", sellerTaxNo);
        queryWrapper.like("company_name", gfmc);
        List<AlsTenantInfoEntity> alsTenantInfoEntities = alsTenantInfoService.list(queryWrapper);
        if (StrUtil.isEmpty(sellerTaxNo)) {
            SellerInvoiceDTO sellerRemoteVo = new SellerInvoiceDTO();
            sellerRemoteVo.setGfmc(gfmc);
            return apiClientService.autoHead(sellerRemoteVo);
        } else {
            if (CollUtil.isNotEmpty(alsTenantInfoEntities)) {
                List<TenantInfoVO> tenantInfoVOS = new ArrayList<>();
                alsTenantInfoEntities.forEach(alsTenantInfoEntity -> {
                    TenantInfoVO tenantInfoVO = new TenantInfoVO();
                    tenantInfoVO.setAccountBlank(alsTenantInfoEntity.getCompanyBankAddress());
                    tenantInfoVO.setBankAccount(alsTenantInfoEntity.getCompanyBankAccount());
                    tenantInfoVO.setKpAddr(alsTenantInfoEntity.getCompanyAddress());
                    tenantInfoVO.setKpCode(alsTenantInfoEntity.getCompanyNo());
                    tenantInfoVO.setKpName(alsTenantInfoEntity.getCompanyName());
                    tenantInfoVO.setKpTel(alsTenantInfoEntity.getCompanyMobile());
                    tenantInfoVO.setEmail(alsTenantInfoEntity.getCompanyEmail());
                    tenantInfoVOS.add(tenantInfoVO);
                });
                return Response.success(tenantInfoVOS);
            } else {
                SellerInvoiceDTO sellerRemoteVo = new SellerInvoiceDTO();
                sellerRemoteVo.setGfmc(gfmc);
                return apiClientService.autoHead(sellerRemoteVo);
            }
        }
    }


    /**
     * @param @param  code
     * @param @return 参数
     * @return Response<List < SupplierInfoVO>>    返回类型
     * @throws
     * @Title: queryList
     * @Description: (根据税号获取纳税主体信息)
     */

    public Response<List> getSubByCode(String code) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        if (StrUtil.isNotBlank(code)) {
            queryWrapper.eq("company_tax_number", code);
        }

        List list = baseMapper.initTenantOrgs(queryWrapper);
        return Response.success(list);
    }


    /**
     * 手工开票
     *
     * @param manmulInvoiceReqVo
     * @return
     */
    public Response manualOpenInvoice(ManmulInvoiceReqVO manmulInvoiceReqVo) {
        SellerInvoiceEntity invoiceEntity = new SellerInvoiceEntity();
        BeanUtils.copyProperties(manmulInvoiceReqVo, invoiceEntity);
        //如果是专票校验必填项
        if ("004".equals(manmulInvoiceReqVo.getInvoiceType()) && "0".equals(manmulInvoiceReqVo.getMakeType())) {
            //购方名称
            if (StrUtil.isEmpty(manmulInvoiceReqVo.getPurchaserName())) {
                return Response.error(CodeConstant.T0001, "购方名称不能为空!");
            }
            //购方税号
            if (StrUtil.isEmpty(manmulInvoiceReqVo.getPurchaserTaxNo())) {
                return Response.error(CodeConstant.T0001, "购方纳税人识别号不能为空!");
            }
            //购方地址电话
            if (StrUtil.isEmpty(manmulInvoiceReqVo.getPurchaserAddressTel())) {
                return Response.error(CodeConstant.T0001, "购方地址电话不能为空!");
            }
            //购方开户行及账号
            if (StrUtil.isEmpty(manmulInvoiceReqVo.getPurchaserBankAccount())) {
                return Response.error(CodeConstant.T0001, "购方开户行及账号不能为空!");
            }
        } else if (StrUtil.isEmpty(manmulInvoiceReqVo.getPurchaserName())) {
            return Response.error(CodeConstant.T0001, "购方名称不能为空!");
        }
        String uuid = UUIDUitl.UUID32(false);
        //明细
        List<SellerInvoiceDetailEntity> invoiceDetailEntity = invoiceEntity.getInvoiceDetail();
        String uuidInvoiceEntit = UUIDUitl.UUID32(false);
        invoiceEntity.setUuid(uuidInvoiceEntit);
        invoiceEntity.setSerialNo(uuid);
        invoiceEntity.setInvoiceState("0");
        invoiceEntity.setMakeInvoiceState("0");
        invoiceEntity.setMakeInvoiceType("0");
        invoiceEntity.setDataSource("0");
        //开启编程式事物
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        //事务状态类，获取事务状态后，Spring根据传播行为来决定如何开启事务
        TransactionStatus status = txManager.getTransaction(def);
        jdbcTemplate = new JdbcTemplate(dataSource);
        try {
            invoicedMapper.insert(invoiceEntity);
            int invoiceSort = 0;
            for (SellerInvoiceDetailEntity sellerInvoiceDetailEntity : invoiceDetailEntity) {
                invoiceSort++;
                sellerInvoiceDetailEntity.setSerialNo(uuid);
                sellerInvoiceDetailEntity.setTaxSign("0");
                sellerInvoiceDetailEntity.setPreferentialMark("0");
                sellerInvoiceDetailEntity.setInvoiceSort(invoiceSort);
                sellerInvoiceDetailEntity.setUuid(UUIDUitl.UUID32(false));
                invoiceDetailMapper.insert(sellerInvoiceDetailEntity);
            }
            txManager.commit(status);

        } catch (DataAccessException e) {
            txManager.rollback(status);
            log.info("插入数据发生错误", e);
            return Response.error();
        }
        return Response.success();
//        List list = new ArrayList();
//        list.add(uuidInvoiceEntit);
//        //开票
//        return openInvoiceService.synchroOpenInvoice(list);
    }


    /**
     * 手工开票
     *
     * @param manmulInvoiceReqVo 发票信息
     * @return 结果
     */
    public Response carManualOpenInvoice(CarManmulInvoiceReqVO manmulInvoiceReqVo) {

        //校验机动车发票参数
        if (checkData(manmulInvoiceReqVo) != null) {
            return Response.error(CodeConstant.T0001, checkData(manmulInvoiceReqVo));
        }

        SellerInvoiceEntity invoiceEntity = new SellerInvoiceEntity();
        BeanUtils.copyProperties(manmulInvoiceReqVo, invoiceEntity);
        String uuid = UUIDUitl.UUID32(false);
        String uuidInvoiceEntit = UUIDUitl.UUID32(false);

        invoiceEntity.setUuid(uuidInvoiceEntit);
        invoiceEntity.setSerialNo(uuid);
        invoiceEntity.setInvoiceState("0");
        invoiceEntity.setMakeInvoiceState("0");
        invoiceEntity.setMakeInvoiceType("0");
        invoiceEntity.setDataSource("0");
        //明细
        SellerInvoiceDetailEntity invoiceDetailEntity = manmulInvoiceReqVo.getInvoiceDetail();
        //开启编程式事物
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        //事务状态类，获取事务状态后，Spring根据传播行为来决定如何开启事务
        TransactionStatus status = txManager.getTransaction(def);
        jdbcTemplate = new JdbcTemplate(dataSource);
        try {
            //添加待开发票
            invoicedMapper.insert(invoiceEntity);
            invoiceDetailEntity.setSerialNo(uuid);
            invoiceDetailEntity.setTaxSign("0");
            invoiceDetailEntity.setPreferentialMark("0");
            invoiceDetailEntity.setInvoiceSort(0);
            invoiceDetailEntity.setUuid(UUIDUitl.UUID32(false));
            invoiceDetailEntity.setGoodsName(invoiceDetailEntity.getCarCategoryName());
            //添加发票明细
            invoiceDetailMapper.insert(invoiceDetailEntity);

            txManager.commit(status);
        } catch (DataAccessException e) {
            txManager.rollback(status);
            log.info("插入数据发生错误", e);
            return Response.error();
        }
        List list = new ArrayList();
        list.add(uuidInvoiceEntit);
        //开票
        return openInvoiceService.synchroOpenInvoice(list);
    }

    private String checkData(CarManmulInvoiceReqVO vo) {
        //机动车发票
        if (StrUtil.isEmpty(vo.getPurchaserTaxNo())) {
            //身份证号
            return "纳税人识别号/统一社会信用代码/身份证号不能为空!";
        }
        if (StrUtil.isEmpty(vo.getPurchaserName())) {
            //购方单位名称
            return "购方单位名称不能为空!";
        }
        if (StrUtil.isEmpty(vo.getSellerPhone())) {
            //销方电话
            return "销方电话不能为空!";
        }
        if (StrUtil.isEmpty(vo.getSellerBankAccount())) {
            //销方账号
            return "销方账号不能为空!";
        }
        if (StrUtil.isEmpty(vo.getSellerDepositBank())) {
            //销方开户银行
            return "开户银行不能为空!";
        }
        if (StrUtil.isEmpty(vo.getDrawer())) {
            //开票人
            return "开票人不能为空!";
        }
        if (vo.getInvoiceDetail() == null) {
            return "车辆信息不能为空!";
        }
        SellerInvoiceDetailEntity sellerInvoiceDetailEntity = vo.getInvoiceDetail();
        //车辆信息
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getProductionCompanyName())) {
            //生产企业
            return "车辆生产企业不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getCarCategoryName())) {
            //车辆类型
            return "车辆类型不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getBrandMode())) {
            //厂牌型号
            return "厂牌型号不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getImportTestimonialNum())) {
            //进口证明书号
            return "进口证明书号不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getInspectionOdd())) {
            //商检单号
            return "商检单号不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getEngineNum())) {
            //发动机号码
            return "发动机号码不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getCarDiscernCode())) {
            //车辆识别代码/车架号码
            return "车辆识别代码/车架号码不能为空!";
        }
        if (sellerInvoiceDetailEntity.getMaximumPeople() == null) {
            //限乘人数
            return "限乘人数不能为空!";
        }
        if (StrUtil.isEmpty(sellerInvoiceDetailEntity.getTaxCode())) {
            //商品编码 taxCode
            return "税收分类编码不能为空!";
        }

        return null;
    }

}

